#include "tvserver.h"
#include <QQuickItem>
#include "threadedimageprovider.h"
#include <QQmlContext>
#include "commontools.h"
#include "sh/shnet.h"
#include "rtools/json.h"
#include <QDebug>
#include "sh/signalfilter.h"

TvServer::TvServer(QObject *parent) :
    QObject(parent)
{
    m_qml = new QtQuick2ApplicationViewer;

    ThreadedImageProvider *threaded = new ThreadedImageProvider(this);
    m_qml->engine()->addImageProvider("threaded", threaded);
    m_qml->rootContext()->setContextProperty("threaded", threaded);

    CommonTools *tools = new CommonTools(this);
    m_qml->rootContext()->setContextProperty("tools", tools);

    m_qml->setMainQmlFile(QStringLiteral("qml/tv-server2/main.qml"));
    m_qml->showExpanded();

    bool ok;
    m_config = Rt::Json::load("config.json", &ok).toMap();
    if (!ok) {
        qWarning() << "No config file!";
        return;
    }

    QVariantMap subnetConf = m_config["sh"].toMap();
    m_sh = new ShNet(this);
    m_sh->join(QHostAddress(subnetConf["interface"].toString()),
            QHostAddress(subnetConf["multicast_group"].toString()),
            subnetConf["port"].toUInt(),
            subnetConf["node_name"].toString(),
            subnetConf["node_groups"].toStringList(),
            subnetConf["node_info"].toMap());

    initSlideshow();
    initRunningLine();
    initVideo();
    m_sh->addFunction("move", this, "move");
    m_sh->addFunction("show", this, "show");
    m_sh->addFunction("save_config", this, "save_config");
    m_sh->addProperty("logo_running", true,
                      m_qml->rootObject()->findChild<QObject*>("logo"),
                      "running");

    m_sh->signalFilter()->connect(Url("rpc/signal1"), this, SLOT(testSlot(int,QString,bool)));

}

void TvServer::testSlot(int a, const QString &b, bool ok)
{
    qDebug() << "I'm called!" << a << b << ok;
}

void TvServer::initSlideshow()
{
    QObject *slideshowObject = m_qml->rootObject()->findChild<QObject*>("slideshow");

    QVariantMap config = m_config["slideshow"].toMap();
    if (!config.contains("media"))
        qWarning() << "slideshow config may be incomplete!";
    slideshowObject->setProperty("imagesFolderPath", config["media"]);

//    QVariantList excludeInt;
//    QStringList excludeVariant = config["exclude"]
//            .toString().split(',', QString::SkipEmptyParts);
//    foreach(QString e, excludeVariant)
//        excludeInt.push_back(e.toInt());
//    slideshowObject->setProperty("excludeFolders", excludeInt);

    m_sh->addProperty("slideshow.running",  true, slideshowObject,  "running");
    m_sh->addProperty("slideshow.x_start",  true, slideshowObject,  "xStart");
    m_sh->addProperty("slideshow.y_start",  true, slideshowObject,  "yStart");
    m_sh->addProperty("slideshow.x_end",  true, slideshowObject,  "xEnd");
    m_sh->addProperty("slideshow.y_end",  true, slideshowObject,  "yEnd");
    m_sh->addProperty("slideshow.scale_start",  true, slideshowObject,  "scaleStart");
    m_sh->addProperty("slideshow.scale_end",  true, slideshowObject,  "scaleEnd");
    m_sh->addProperty("slideshow.duration",  true, slideshowObject,  "duration");
    m_sh->addProperty("slideshow.exclude", true, slideshowObject, "excludeFolders");
}

void TvServer::initRunningLine()
{
    QObject *lineObject = m_qml->rootObject()->findChild<QObject*>("running_line");
    m_sh->addProperty("line.running",  true, lineObject,  "running");
    m_sh->addProperty("line.speed",  true, lineObject,  "speed");
    m_sh->addProperty("line.text",  true, lineObject,  "text");
    m_sh->addProperty("line.color",  true, lineObject,  "color");
    m_sh->addProperty("line.size",  true, lineObject,  "size");
    m_sh->addProperty("line.font",  true, lineObject,  "font");
    m_sh->addProperty("line.height",  true, lineObject,  "height");
    m_sh->addProperty("line.step", true, lineObject, "step");
}

void TvServer::initVideo()
{
    QObject *videoObject = m_qml->rootObject()->findChild<QObject*>("video");

    QVariantMap config = m_config["video"].toMap();
    if (!config.contains("media"))
        qWarning() << "video config may be incomplete!";
    videoObject->setProperty("videosFolderPath", config["media"]);

//    QVariantList excludeInt;
//    QStringList excludeVariant = config["exclude"]
//            .toString().split(',', QString::SkipEmptyParts);
//    foreach(QString e, excludeVariant)
//        excludeInt.push_back(e.toInt());
//    videoObject->setProperty("excludeVideos", excludeInt);

    m_sh->addProperty("video.running", true, videoObject, "running");
//    m_sh->addProperty(videoObject, true, "exclude", "excludeVideos");
}

// Sh functions
QVariant TvServer::move(const QVariant &args)
{
    QVariantList argsList = args.toList();
    if (argsList.size() != 2)
        return "wrong arguments";
    int x = argsList[0].toInt();
    int y = argsList[1].toInt();
    m_qml->setPosition(x, y);
    return "ok";
}

QVariant TvServer::show(const QVariant &args)
{
    QVariantList argsList = args.toList();
    if (argsList.size() != 1)
        return "wrong arguments";
    QString showType = argsList[0].toString();
    if (showType == "fullscreen")
        m_qml->showFullScreen();
    if (showType == "normal")
        m_qml->showNormal();
    if (showType == "hide")
        m_qml->hide();
    return "ok";
}

QVariant TvServer::save_config(const QVariant &args)
{
    QVariantMap slideshowConfig = m_config["slideshow"].toMap();
    QObject *slideshowObject = m_qml->rootObject()->findChild<QObject*>("slideshow");
    slideshowConfig["duration"] = slideshowObject->property("duration").toString();
    slideshowConfig["x_start"] = slideshowObject->property("xStart").toString();
    slideshowConfig["y_start"] = slideshowObject->property("yStart").toString();
    slideshowConfig["x_end"] = slideshowObject->property("xEnd").toString();
    slideshowConfig["y_end"] = slideshowObject->property("yEnd").toString();
    slideshowConfig["scale_start"] = slideshowObject->property("scaleStart").toString();
    slideshowConfig["scale_end"] = slideshowObject->property("scaleEnd").toString();
    slideshowConfig["exclude"] = slideshowObject->property("excludeFolders").toString();
    m_config["slideshow"] = slideshowConfig;
    Rt::Json::save("config.json", m_config);

    return "ok";
}
